package com.fxkj.cloud.drms.infra.repository;

import com.fxkj.cloud.dbs.common.constants.WsMsgEnum;
import com.fxkj.cloud.dbs.common.model.DeviceBasicInfo;
import com.fxkj.cloud.dbs.common.model.kv.TsKvEntry;
import com.fxkj.cloud.dbs.common.model.linkage.DeviceAttributeKeyValue;
import com.fxkj.cloud.dbs.common.model.ws.DeviceStatusInfo;
import com.fxkj.cloud.dbs.common.model.ws.FxWsMsg;
import com.fxkj.cloud.drms.domain.device.repository.DeviceRepository;
import com.fxkj.cloud.drms.domain.linkage.LinkageProcessorService;
import com.fxkj.cloud.drms.domain.ts.repository.TimeseriesRepository;
import com.fxkj.cloud.drms.domain.ts.service.InternalTelemetryService;
import com.fxkj.cloud.drms.domain.ws.service.FxWsClient;
import com.google.common.util.concurrent.FutureCallback;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

/**
 * <p>description: </p>
 * @author ww
 * @date 2025/3/18 9:21
 */
@Service
public class DefaultTelemetryService implements InternalTelemetryService {
    private final TimeseriesRepository timeseriesRepository;
    private final FxWsClient wsClient;
    private final LinkageProcessorService linkageProcessorService;
    private final DeviceRepository deviceRepository;

    public DefaultTelemetryService(TimeseriesRepository timeseriesRepository, FxWsClient wsClient, LinkageProcessorService linkageProcessorService, DeviceRepository deviceRepository) {
        this.timeseriesRepository = timeseriesRepository;
        this.wsClient = wsClient;
        this.linkageProcessorService = linkageProcessorService;
        this.deviceRepository = deviceRepository;
    }

    @Override
    public void saveAndNotify(String deviceSerialNo, List<TsKvEntry> ts, FutureCallback<Void> callback) {
        DeviceBasicInfo deviceBasicInfo = deviceRepository.getDeviceBasicInfoByDeviceSerialNo(deviceSerialNo);
        if (null == deviceBasicInfo) {
            callback.onFailure(new RuntimeException("设备不存在"));
            return;
        }
        doSaveAndNotify(deviceBasicInfo.getOrganizationId(), deviceBasicInfo.getProductId(), deviceBasicInfo.getDeviceId(), ts, callback);
    }

    private void doSaveAndNotify(UUID rootOrganizationId, UUID productId, UUID deviceId, List<TsKvEntry> ts, FutureCallback<Void> callback) {
        saveAndNotifyInternal(rootOrganizationId, productId, deviceId, ts, callback);
    }

    @Override
    public void saveAndNotifyInternal(UUID rootOrganizationId, UUID productId, UUID deviceId, List<TsKvEntry> ts, FutureCallback<Void> callback) {
        //保存数据
        timeseriesRepository.save(rootOrganizationId, productId, deviceId, ts);
        //发送websocket消息
        wsClient.pushNotificationToOrganization(rootOrganizationId, new FxWsMsg(WsMsgEnum.DEVICE_TELEMETRY_DATA, DeviceAttributeKeyValue.list(ts)));
        //物联场景处理
        linkageProcessorService.process(deviceId, ts);
    }
}
